<!DOCTYPE html>
<html lang="zh-cn">
  <head>
    <!-- Meta, title, CSS, favicons, etc. -->
    <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="文档管理">
<meta name="author" content="文档管理">
<title>配置指南 文档管理</title>
<link href="./assets/css/bootstrap.min.css" rel="stylesheet">
<!-- Documentation extras -->
<link href="./assets/css/docs.css" rel="stylesheet">
<link href="./assets/css/style.css" rel="stylesheet">
<link href="http://cdn.bootcss.com/highlight.js/7.3/styles/github.min.css" rel="stylesheet">
<style>
body{font-family:"ff-tisa-web-pro-1","ff-tisa-web-pro-2","Lucida Grande","Helvetica Neue",Helvetica,Arial,"Hiragino Sans GB","Hiragino Sans GB W3","WenQuanYi Micro Hei",sans-serif;}
h1, .h1, h2, .h2, h3, .h3, h4, .h4, .lead {font-family:"ff-tisa-web-pro-1","ff-tisa-web-pro-2","Lucida Grande","Helvetica Neue",Helvetica,Arial,"Hiragino Sans GB","Hiragino Sans GB W3","Microsoft YaHei UI","Microsoft YaHei","WenQuanYi Micro Hei",sans-serif;}
pre code { background: transparent; }
@media (min-width: 768px) {
    .bs-docs-home .bs-social, 
    .bs-docs-home .bs-masthead-links {
      margin-left: 0;
    }
}
.bs-docs-section p {
	line-height: 2;
}
.bs-docs-section p.lead {
	line-height: 1.4;
}
</style>
<!--[if lt IE 9]><script src="../docs-assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
  <script src="http://cdn.bootcss.com/html5shiv/3.7.0/html5shiv.min.js"></script>
  <script src="http://cdn.bootcss.com/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
<!-- Favicons -->
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="../docs-assets/ico/apple-touch-icon-144-precomposed.png">
<link rel="shortcut icon" href="../docs-assets/ico/favicon.png">
  </head>
  <body>
    <a class="sr-only" href="#content">Skip to main content</a>

    <!-- Docs master nav -->
    <header class="navbar navbar-inverse navbar-fixed-top bs-docs-nav" role="banner">
  <div class="container">
    <div class="navbar-header">
      <button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".bs-navbar-collapse">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a href="./overview.html" class="navbar-brand">文档管理</a>
    </div>
    <nav class="collapse navbar-collapse bs-navbar-collapse" role="navigation">
      <ul class="nav navbar-nav">
       		<li  ><a href="overview.html">简介</a></li>
            <li ><a href="download.html">下载</a></li>
            <li ><a href="userguide.html">开发指南</a></li>
            <li class='active'><a href="config.html" class="selected">配置指南</a></li>
            <li ><a href="syntax.html">语法指南</a></li>
            <li ><a href="integrate.html">Web 框架集成</a></li>
            <!--
            <li ><a href="example.html">例子</a></li>
            -->
            <li ><a href="faq.html">FAQ</a></li>
            <li ><a href="about.html">关于</a></li>
      </ul>
    </nav>
  </div>
</header>
    <!-- Docs page layout -->
    <div class="bs-header" id="content">
      <div class="container">
        <h2>配置指南</h2>
        <p></p>
      </div>
    </div>
	<a href="#top" id="toTop"></a>
    <!-- Callout for the old docs link -->
    <div class="container bs-docs-container">
      <div class="row">
        <div class="col-md-3">
          <div class="bs-sidebar hidden-print" role="complementary">
            <ul class="nav bs-sidenav">
            <li><a href="#x1106755817">1 全局配置选项</a></li>
            <li><a href="#x71556755">&nbsp&nbsp1.1 全局定义(包/类/变量)</a></li>
            <li><a href="#x817993292">&nbsp&nbsp1.2 扩展方法/函数/标签</a></li>
            <li><a href="#x1497214921">&nbsp&nbsp1.3 模板路径和编码格式</a></li>
            <li><a href="#x1095099928">&nbsp&nbsp1.4 语法选项</a></li>
            <li><a href="#x1004799563">&nbsp&nbsp1.5 编译选项</a></li>
            <li><a href="#x818233124">&nbsp&nbsp1.6 安全管理器</a></li>
            <li><a href="#x867245599">&nbsp&nbsp1.7 注释指令</a></li>
            <li><a href="#x641838512">&nbsp&nbsp1.8 其他选项</a></li>
            <li><a href="#x793518697">&nbsp&nbsp1.9 推荐配置</a></li>
            </ul>
          </div>
        </div>
	        <div class="col-md-9" role="main">
	         <div class="bs-docs-section">
	           <h1 id="x1106755817" class="page-header"><span>1 全局配置选项</span></h1> 
<table> 
 <thead> 
  <tr> 
   <th>名称 </th> 
   <th>说明 </th> 
   <th>默认值 </th> 
  </tr> 
 </thead> 
 <tbody> 
  <tr> 
   <td><a href="#import.packages">import.packages</a> </td> 
   <td>默认导入的 java 包 </td> 
   <td> </td> 
  </tr> 
  <tr> 
   <td><a href="#import.classes">import.classes</a> </td> 
   <td>默认导入的 java 类 </td> 
   <td> </td> 
  </tr> 
  <tr> 
   <td><a href="#import.variables">import.variables</a> </td> 
   <td>默认导入的 java 对象 </td> 
   <td> </td> 
  </tr> 
  <tr> 
   <td><a href="#import.methods">import.methods</a> </td> 
   <td>默认导入的扩展方法 </td> 
   <td> </td> 
  </tr> 
  <tr> 
   <td><a href="#import.functions">import.functions</a> </td> 
   <td>默认导入的扩展函数 </td> 
   <td> </td> 
  </tr> 
  <tr> 
   <td><a href="#import.tags">import.tags</a> </td> 
   <td>默认导入的自定义标签 tags </td> 
   <td> </td> 
  </tr> 
  <tr> 
   <td><a href="#import.autoscan">import.autoscan</a> </td> 
   <td>是否自动扫描用户自定义扩展 Class </td> 
   <td>false </td> 
  </tr> 
  <tr> 
   <td><a href="#import.autoscan.packages">import.autoscan.packages</a> </td> 
   <td>在指定的包中进行自动扫描 </td> 
   <td> </td> 
  </tr> 
  <tr> 
   <td><a href="#global.variables">global.variables</a> </td> 
   <td>配置全局变量 </td> 
   <td> </td> 
  </tr> 
  <tr> 
   <td><a href="#input.encoding">input.encoding</a> </td> 
   <td>模板源文件的编码格式 </td> 
   <td>utf-8 </td> 
  </tr> 
  <tr> 
   <td><a href="#output.encoding">output.encoding</a> </td> 
   <td>模板输出编码格式 </td> 
   <td>utf-8 </td> 
  </tr> 
  <tr> 
   <td><a href="#syntax.safecall">syntax.safecall</a> </td> 
   <td>是否默认启用全局的安全调用 </td> 
   <td>false </td> 
  </tr> 
  <tr> 
   <td><a href="#template.loader">template.loader</a> </td> 
   <td>模板资源载入Class </td> 
   <td>jetbrick.template.resource.loader.FileSystemResourceLoader </td> 
  </tr> 
  <tr> 
   <td><a href="#template.path">template.path</a> </td> 
   <td>模板资源的根目录 </td> 
   <td>当前目录 </td> 
  </tr> 
  <tr> 
   <td><a href="#template.suffix">template.suffix</a> </td> 
   <td>默认模板文件扩展名 </td> 
   <td>.jetx </td> 
  </tr> 
  <tr> 
   <td><a href="#template.reloadable">template.reloadable</a> </td> 
   <td>是否允许热加载 </td> 
   <td>false </td> 
  </tr> 
  <tr> 
   <td><a href="#compile.tool">compile.tool</a> </td> 
   <td>编译器 </td> 
   <td>jetbrick.template.compiler.JdkCompiler </td> 
  </tr> 
  <tr> 
   <td><a href="#compile.strategy">compile.strategy</a> </td> 
   <td>编译策略 </td> 
   <td>always </td> 
  </tr> 
  <tr> 
   <td><a href="#compile.debug">compile.debug</a> </td> 
   <td>是否允许输出 debug 信息 </td> 
   <td>false </td> 
  </tr> 
  <tr> 
   <td><a href="#compile.path">compile.path</a> </td> 
   <td>默认编译输出路径 </td> 
   <td>系统TEMP目录下面的 jetx 目录 </td> 
  </tr> 
  <tr> 
   <td><a href="#security.manager">security.manager</a> </td> 
   <td>安全管理器实现类 </td> 
   <td> </td> 
  </tr> 
  <tr> 
   <td><a href="#security.manager.file">security.manager.file</a> </td> 
   <td>安全管理器黑白名单文件 </td> 
   <td> </td> 
  </tr> 
  <tr> 
   <td><a href="#security.manager.namelist">security.manager.namelist</a> </td> 
   <td>安全管理器黑白名单列表 </td> 
   <td> </td> 
  </tr> 
  <tr> 
   <td><a href="#trim.directive.line">trim.directive.line</a> </td> 
   <td>是否要删除指令行两边的空白 </td> 
   <td>true </td> 
  </tr> 
  <tr> 
   <td><a href="#trim.directive.comments">trim.directive.comments</a> </td> 
   <td>是否支持指令两边增加注释对 </td> 
   <td>false </td> 
  </tr> 
  <tr> 
   <td><a href="#trim.directive.comments.prefix">trim.directive.comments.prefix</a> </td> 
   <td>指令注释的开始部分 </td> 
   <td>&lt;!-- </td> 
  </tr> 
  <tr> 
   <td><a href="#trim.directive.comments.suffix">trim.directive.comments.suffix</a> </td> 
   <td>指令注释的结束部分 </td> 
   <td>--&gt; </td> 
  </tr> 
 </tbody> 
</table> 
<blockquote>
 <p><strong>注意</strong>：</p> 
 <ol> 
  <li>所有配置选项都必须在 <code>JetEngine</code> 初始化的时候指定，不允许动态修改。</li> 
  <li>所有配置选项都支持变量啦，具体参考 <a href="#output.encoding"><code>template.path</code></a> 或者 <a href="#compile.path"><code>compile.path</code></a> 中的例子。</li> 
 </ol> 
</blockquote>
<h2 id="x71556755" class="page-header"><span>1.1 全局定义(包/类/变量)</span></h2>
<p>在模板中，如果要用到一些其他的 Class, 那么可以先 import 进来，这样就可以在模板中使用短名字，比如 <code>Date</code> 而不是 <code>java.util.Date</code>。</p>
<p><a name="import.packages"></a></p>
<h3 id="x2047664874" class="page-header"><span>1.1.1 import.packages</span></h3>
<p>用来配置包名，会自动导入包下面的所有类。允许配置多个包名，用逗号分隔。</p>
<p>支持三种方式，如下：<br />1. <code>jetbrick.schema.app.model</code><br />2. <code>jetbrick.schema.app.methods.*</code><br />3. <code>jetbrick.schema.**</code></p>
<p>其中 <code>1</code> 和 <code>2</code> 是一样的，会自动导入包下面的所有 Class 文件，但是不包含子包。<br />而方式 <code>3</code> 会自动将子包下面的 Class 也一起导入进来。</p>
<p>示例如下：</p> 
<div class="highlight">
 <pre><code class="language-html">import.packages = jetbrick.schema.app.model, jetbrick.schema.app.methods.*, jetbrick.schema.**
</code></pre>
</div> 
<blockquote>
 <p><strong>注意</strong>：<code>jetbrick-template</code> 会自动引入 <code>java.lang.*</code> 和 <code>java.util.*</code>。</p> 
</blockquote>
<p><a name="import.classes"></a></p>
<h3 id="x206485795" class="page-header"><span>1.1.2 import.classes</span></h3>
<p>用来配置单个类名，优先级比 <code>import.packages</code> 高。允许配置多个类名，用逗号分隔。</p>
<p>示例如下：</p> 
<div class="highlight">
 <pre><code class="language-html">import.classes = java.io.File, java.util.List
</code></pre>
</div>
<p><a name="import.variables"></a></p>
<h3 id="x937641362" class="page-header"><span>1.1.3 import.variables</span></h3>
<p>在一个 webapp 中，我们希望每个模板都自动引入一些变量，比如 <code>HttpServletRequest request</code>，那么我们就可以在这里定义。</p>
<p>允许配置多个变量定义，用逗号分隔。示例如下：</p> 
<div class="highlight">
 <pre><code class="language-html">import.variables = HttpServletRequest request
import.variables = jetbrick.orm.Pagelist pagelist, List&lt;Entity&gt; entites
</code></pre>
</div>
<p>变量的类型可以使用泛型定义，并且会自动在 <code>import.packages</code> 和 <code>import.classes</code> 里面查找 Class。</p> 
<blockquote>
 <p><strong>注意</strong>：全局定义的变量如果在模板中被重新定义成其他类型(<code>#define</code>, <code>#set</code>)，则以模板定义优先。</p> 
</blockquote>
<h2 id="x817993292" class="page-header"><span>1.2 扩展方法/函数/标签</span></h2>
<p><a name="import.methods"></a></p>
<h3 id="x104572311" class="page-header"><span>1.2.1 import.methods</span></h3>
<p>我们知道一个 Java Class 的 所有 methods 都是定义在同一个 class 文件中的，不能在其他地方进行动态扩展。但是一些其他动态语言却支持在 Class 外部为这个 Class 增加一些方法。比如：</p> 
<ul> 
 <li>JavaScript 的 prototype 机制</li> 
 <li>Groovy 的 metaClass 机制</li> 
 <li>Kotlin</li> 
</ul>
<p>jetbrick-template 也在这里带给大家强大的动态方法扩展机制。<br />具体参考： <a href="userguide.html#methods">jetbrick-template 动态方法扩展</a></p>
<p>这里就是把实现了动态扩展的 Method Class 注册到 JetEngine 中。允许配置多个 Class 定义，用逗号分隔。示例如下：</p> 
<div class="highlight">
 <pre><code class="language-html">import.methods = StringMethods, app.project.methods.UserAuthMethods
</code></pre>
</div>
<p>定义的类名会自动在 <code>import.packages</code> 里面查找 Class。</p>
<p><code>jetbrick-template</code> 默认会注册 <code>jetbrick.template.runtime.JetMethods</code>，<br />具体参考：<a href="syntax.html#default_methods">默认的方法扩展 Methods</a>。</p>
<p><a name="import.functions"></a></p>
<h3 id="x995736430" class="page-header"><span>1.2.2 import.functions</span></h3>
<p>和 <code>import.methods</code> 类似，我们还支持在模板中使用函数。</p>
<p>允许配置多个 Function Class 定义，用逗号分隔。示例如下：</p> 
<div class="highlight">
 <pre><code class="language-html">import.functions = app.project.methods.UserAuthFunctions
</code></pre>
</div>
<p><code>jetbrick-template</code> 默认会注册 <code>jetbrick.template.runtime.JetFunctions</code>，<br />具体参考：<a href="syntax.html#default_functions">默认的函数扩展 Functions</a>。</p>
<p><a name="import.tags"></a></p>
<h3 id="x1423734978" class="page-header"><span>1.2.3 import.tags</span></h3>
<p>我们支持在模板中自定义标签 #tag。</p>
<p>允许配置多个 Tag Class 定义，用逗号分隔。示例如下：</p> 
<div class="highlight">
 <pre><code class="language-html">import.tags = app.project.tags.UserTags
</code></pre>
</div>
<p><code>jetbrick-template</code> 默认会注册 <code>jetbrick.template.runtime.JetTags</code>，<br />具体参考：<a href="syntax.html#default_tags">默认的自定义标签 Tags</a>。</p>
<p><a name="import.autoscan"></a></p>
<h3 id="x1358889771" class="page-header"><span>1.2.4 import.autoscan</span></h3>
<p>是否自动扫描用户自定义的扩展 Class，扫描的内容是： <strong>扩展方法，扩展函数，自定义标签</strong></p>
<p>默认 <code>false</code>，不启用。</p>
<p><a name="import.autoscan.packages"></a></p>
<h3 id="x1904023066" class="page-header"><span>1.2.5 import.autoscan.packages</span></h3>
<p>在指定的包下面进行自动扫描，如果为空，那么扫描整个 classpath。支持定义多个包。</p> 
<div class="highlight">
 <pre><code class="language-html">import.autoscan = true
import.autoscan.packages = app.methods, app.functions, app.tags
</code></pre>
</div> 
<blockquote>
 <p><strong>注意</strong>：</p> 
 <ol> 
  <li>扫描整个 classpath 需要花费一定的时间（大约每秒10000个类），建议配置 <code>import.autoscan.packages</code> 以加快速度。</li> 
  <li>由于不会对扫描的 class 加载到 jvm 中，所以不会产生 OOM。</li> 
 </ol> 
</blockquote>
<p>更多详细内容请参考： <a href="faq-autoscan.html">如何让自动扫描发现用户自定义的扩展方法/函数/标签 Class</a></p>
<h2 id="x1497214921" class="page-header"><span>1.3 模板路径和编码格式</span></h2>
<p><a name="input.encoding"></a></p>
<h3 id="x1175775991" class="page-header"><span>1.3.1 input.encoding</span></h3>
<p>模板源文件的编码格式，默认为 <code>utf-8</code>。</p>
<p><a name="output.encoding"></a></p>
<h3 id="x1773115296" class="page-header"><span>1.3.2 output.encoding</span></h3>
<p>模板输出内容的编码格式，默认为 <code>utf-8</code>。</p> 
<blockquote>
 <p><strong>注意</strong>：一般在 web 中，<code>output.encoding</code> 应该和 html 页面的 <code>contentType</code> 中的编码，以及 <code>response</code> 的 <code>characterEncoding</code> 完全一致。</p> 
</blockquote>
<h2 id="x1095099928" class="page-header"><span>1.4 语法选项</span></h2>
<p><a name="syntax.safecall"></a></p>
<h3 id="x314646806" class="page-header"><span>1.4.1 syntax.safecall</span></h3>
<p>jetbrick-template 支持 4 种方法的安全调用（类似于 Groovy），以避免出现 <code>NullPointerException</code></p> 
<ol> 
 <li>属性调用 <code>bean?.property</code></li> 
 <li>方法调用 <code>bean?.method(...)</code></li> 
 <li>数组访问 <code>array?[index]</code></li> 
 <li>Map访问 <code>map?[key]</code></li> 
</ol>
<p>如果 <code>syntax.safecall = true</code>，那么将会把全局默认的语法变成安全调用语法。<br />如 <code>bean.property</code> 将等价于 <code>bean?.property</code>。这样我就可以省略 <code>?</code> 拉。 </p>
<p>默认为 <code>false</code>，不启用。</p>
<p><a name="template.loader"></a></p>
<h3 id="x1970607097" class="page-header"><span>1.4.2 template.loader</span></h3>
<p>如何找到我们自己的模板文件呢？这里就是定义我们要使用的查找类。我们支持下面几种 Class</p> 
<div class="highlight">
 <pre><code class="language-html">template.loader = jetbrick.template.resource.loader.FileSystemResourceLoader
template.loader = jetbrick.template.resource.loader.ClasspathResourceLoader
template.loader = jetbrick.template.resource.loader.JarResourceLoader
template.loader = jetbrick.template.web.WebResourceLoader
template.loader = jetbrick.template.resource.loader.MultipathResourceLoader
</code></pre>
</div>
<p>默认为 <code>jetbrick.template.resource.loader.FileSystemResourceLoader</code>。</p>
<p>注意：如果是 Web 集成模式，默认值为 <code>jetbrick.template.web.WebResourceLoader</code>。</p>
<p><a name="template.path"></a></p>
<h3 id="x225407719" class="page-header"><span>1.4.3 template.path</span></h3>
<p>除了要定义 <code>template.loader</code>，我们还需要定义模板存放的根目录。</p>
<p>默认为系统当前目录：<code>System.getProperty(&quot;user.dir&quot;)</code>。</p>
<p>注意：如果是 web 集成模式，默认为 webapp 的根目录。具体请参考：<a href="integrate.html#JetEngine">JetEngine 自动加载方式</a> 中注意事项。</p> 
<ul> 
 <li>从文件系统加载</li> 
</ul> 
<div class="highlight">
 <pre><code class="language-html">template.loader = jetbrick.template.resource.loader.FileSystemResourceLoader
template.path = /opt/app/templates/
</code></pre>
</div> 
<ul> 
 <li>从Classpath下加载</li> 
</ul> 
<div class="highlight">
 <pre><code class="language-html">template.loader = jetbrick.template.resource.loader.ClasspathResourceLoader
template.path = /META-INF/templates/
</code></pre>
</div> 
<ul> 
 <li>从jar包中加载</li> 
</ul> 
<div class="highlight">
 <pre><code class="language-html">template.loader = jetbrick.template.resource.loader.JarResourceLoader
template.path = /opt/app/templates.jar
</code></pre>
</div> 
<ul> 
 <li>从webapp目录中加载(仅在Web框架集成中有效，并且已经被设置为默认项)</li> 
</ul> 
<div class="highlight">
 <pre><code class="language-html">template.loader = jetbrick.template.web.WebResourceLoader
template.path = /WEB-INF/templates
</code></pre>
</div> 
<ul> 
 <li>从多个目录中加载</li> 
</ul> 
<div class="highlight">
 <pre><code class="language-html">template.loader = jetbrick.template.resource.loader.MultipathResourceLoader
template.path = file:/path/to, classpath:/, jar:/path/to/sample.jar, webapp:/WEB-INF/templates
</code></pre>
</div>
<p>注意：<code>template.path</code> 支持多种路径，由逗号分隔。每个路径由一个前缀开头，代表相应的 ResouceLoader。具体如下：</p> 
<table> 
 <thead> 
  <tr> 
   <th>前缀 </th> 
   <th>代表的 ResourceLoader </th> 
  </tr> 
 </thead> 
 <tbody> 
  <tr> 
   <td>file: </td> 
   <td>FileSystemResourceLoader </td> 
  </tr> 
  <tr> 
   <td>classpath: </td> 
   <td>ClasspathResourceLoader </td> 
  </tr> 
  <tr> 
   <td>jar: </td> 
   <td>JarResourceLoader </td> 
  </tr> 
  <tr> 
   <td>webapp: </td> 
   <td>WebResourceLoader </td> 
  </tr> 
  <tr> 
   <td>&lt;MyClassLoader&gt;:</td> 
   <td>用户自定义的 ResourceLoader (完整类名) </td> 
  </tr> 
 </tbody> 
</table>
<p><font color="red"><br />现在 <code>template.path</code> 支持变量了，如：<br /></font></p> 
<div class="highlight">
 <pre><code class="language-html">template.path = ${user.dir}/templates
template.path = ${webapp.dir}/WEB-INF/templates
</code></pre>
</div>
<p>那么我们支持哪些变量呢？其实这些变量都来自于 <code>System.getProperty(name)</code>，只要 <code>System</code> 里有的，都支持。<br />其中 <code>webapp.dir</code> 是个特殊变量，由 Web 集成框架在系统启动的时候，通过 <code>System.setProperty(&quot;webapp.dir&quot;, servletContext.getRealPath(&quot;/&quot;))</code> 设置的。</p>
<p><a name="template.suffix"></a></p>
<h3 id="x1764510907" class="page-header"><span>1.4.4 template.suffix</span></h3>
<p>默认的模板文件扩展名 <code>.jetx</code>，主要用于 Web 框架集成中，用于查找和过滤模板用。</p>
<p><a name="template.reloadable"></a></p>
<h3 id="x674610073" class="page-header"><span>1.4.5 template.reloadable</span></h3>
<p>在开发模式下面，我们一般需要频繁的修改模板内容来进行调试。那么我们需要打开这个功能来支持模板的热部署。（类似于 <code>JSP</code>）</p>
<p>是否需要重新编译和加载模板，取决于模板源文件的最后修改时间。</p>
<p>默认为 <code>false</code>，建议只在开发模式中启用。</p>
<h2 id="x1004799563" class="page-header"><span>1.5 编译选项</span></h2>
<p>jetbrick-template 采用编译成 Java ByteCode 来提高性能。</p>
<p><a name="compile.tool"></a></p>
<h3 id="x94810227" class="page-header"><span>1.5.1 compile.tool</span></h3>
<p>模板编译器的配置，默认使用 JDK 自带的编译器 （需要使用 JDK，而不是 JRE），也支持 Eclipse Java Compiler。</p>
<p>目前可选的配置如下：</p> 
<div class="highlight">
 <pre><code class="language-html"># 使用 JDK Compiler (默认值)
compile.tool = jetbrick.template.compiler.JdkCompiler

# 使用 Eclipse Java Compiler 
compile.tool = jetbrick.template.compiler.JdtCompiler
</code></pre>
</div>
<p>Eclipse Java Compiler 需要引入第三方 jar (Tomcat 等 WebServer 一般都自带该 jar)</p> 
<div class="highlight">
 <pre><code class="language-html">&lt;dependency&gt;
    &lt;groupId&gt;org.eclipse.jdt.core.compiler&lt;/groupId&gt;
    &lt;artifactId&gt;ecj&lt;/artifactId&gt;
    &lt;version&gt;4.3.1&lt;/version&gt;
&lt;/dependency&gt;
</code></pre>
</div> 
<ol> 
 <li>对于不支持 <code>javax.tools.JavaCompiler</code> 接口的 BAE (Baidu App Engine), 可以切换到改编译器。</li> 
 <li>对于出现未知的编译错误的时候，可以尝试切换到该编译器。</li> 
</ol>
<p><a name="compile.strategy"></a></p>
<h3 id="x511378638" class="page-header"><span>1.5.2 compile.strategy</span></h3>
<p>模板从 1.2.0 开始，提供更加灵活的编译策略。由下面 4 中情况</p> 
<div class="highlight">
 <pre><code class="language-html">compile.strategy = precompile
compile.strategy = always
compile.strategy = auto
compile.strategy = none
</code></pre>
</div> 
<ul> 
 <li><p><code>precompile</code><br />在 JetEngine 初始化的时候，自动获取所有的模板(根据 <code>template.suffix</code> 过滤)，然后启动一个独立的线程进行编译。<br />这样虽然启动时间会增加，但是后面的模板访问将会非常的快。并且在预编译没有完成期间，应用可以正常访问，不冲突。</p></li> 
 <li><p><code>always</code> （默认值）<br />就是在模板被首次访问的时候，进行编译。</p></li> 
 <li><p><code>auto</code><br />就是在模板被首次访问的时候，如果磁盘中已经存在编译好的 Class 文件（并且源文件没有改变），那么直接加载该 Class 文件，否则进行编译。</p></li> 
 <li><p><code>none</code><br />改模式下，将不在对模板进行编译。（发布的时候，用户无需发布任何模板源文件）<br />用户必须通过 <code>JetxGenerateApp</code> 预编译工具，事先将模板全部编译成 class 文件，并将所有的 class 文件放在 classpath 下面。<br />注意： class 文件放在 classpath 下面，而不是 <code>compile.path</code> 对应的目录。</p></li> 
</ul> 
<blockquote>
 <p>注意：<br />不管采用什么模式，对于使用 <code>JetEngine.createTemplate(source)</code> 直接由源码创建的模板，仍然需要进行编译。 </p> 
</blockquote>
<p><a name="compile.debug"></a></p>
<h3 id="x1370936616" class="page-header"><span>1.5.3 compile.debug</span></h3>
<p>是否在日志中打印输出模板生成的 Java Source 源代码。</p>
<p>默认 <code>false</code>，建议在开发模式中启用。</p> 
<blockquote>
 <p><strong>注意</strong>：同时需要 slf4j 的配合才能输出日志。默认已经开启了 <code>INFO</code> 级别的日志。</p> 
</blockquote>
<p><a name="compile.path"></a></p>
<h3 id="x94677760" class="page-header"><span>1.5.4 compile.path</span></h3>
<p>在模板编译的时候，会先生成对应的 <code>.java</code> 文件，然后在把 <code>.java</code> 文件编译成 <code>.class</code> 文件。我们生成的这 2 种文件就放在这个目录下面。</p>
<p>在用 Eclipse 进行 debug 的时候，可以 link 这个目录为 sourcepath 来进行 debug。<br />具体参考：<a href="userguide.html#debug">如何调试模板 debug？</a></p>
<p>默认会在系统TEMP目录 <code>System.getProperty(&quot;java.io.tmpdir&quot;)</code> 下面新建一个 <code>jetx</code> 目录。如果这个目录非法或者没有写的权限，那么就会抛出 Exception。</p> 
<blockquote>
 <p><strong>注意</strong>：</p> 
 <ul> 
  <li>如果一个应用中使用多个 <code>JetEngine</code> 实例，请配置不同的 <code>compile.path</code> 防止出现冲突。我们建议用户每次都重定义这个路径。</li> 
 </ul> 
</blockquote>
<p><font color="red"><br />现在 <code>compile.path</code> 支持变量了，如：<br /></font></p> 
<div class="highlight">
 <pre><code class="language-html">compile.path = ${java.io.tmp}/jetx
compile.path = ${webapp.dir}/WEB-INF/jetx_classes
</code></pre>
</div>
<p>那么我们支持哪些变量呢？其实这些变量都来自于 <code>System.getProperty(name)</code>，只要 <code>System</code> 里有的，都支持。<br />其中 <code>webapp.dir</code> 是个特殊变量，由 Web 集成框架在系统启动的时候，通过 <code>System.setProperty(&quot;webapp.dir&quot;, servletContext.getRealPath(&quot;/&quot;))</code> 设置的。</p>
<h2 id="x818233124" class="page-header"><span>1.6 安全管理器</span></h2>
<p>从 1.2.0 开始，模块新增了安全管理器，特别适合于 CMS 软件，允许用户自定义模板的场景。</p>
<p><a name="security.manager"></a></p>
<h3 id="x1132877567" class="page-header"><span>1.6.1 security.manager</span></h3>
<p>配置安全管理器的实现类，默认为空，表示禁用安全管理器。</p>
<p>启用方式(使用默认的安全管理器)：</p> 
<div class="highlight">
 <pre><code class="language-html">security.manager = jetbrick.template.parser.JetSecurityManagerImpl
</code></pre>
</div>
<p>用户也可以实现自己的安全管理器，只要实现接口： <code>jetbrick.template.JetSecurityManager</code> 即可。</p>
<p>安全管理器只在对模板进行解析编译的时候进行，运行期不会影响任何性能。</p>
<p><a name="security.manager.file"></a></p>
<h3 id="x1994088203" class="page-header"><span>1.6.2 security.manager.file</span></h3>
<p>给默认的安全管理器，配置黑白名单，将该名单放在独立的外部文件中。（每行一个名单）</p> 
<div class="highlight">
 <pre><code class="language-html">security.manager.file = ${webapp.dir}/WEB-INF/jetx-white-black-list.txt
</code></pre>
</div>
<p><a name="security.manager.namelist"></a></p>
<h3 id="x1718482872" class="page-header"><span>1.6.3 security.manager.namelist</span></h3>
<p>给默认的安全管理器，配置黑白名单，多个名单以逗号分隔。</p> 
<div class="highlight">
 <pre><code class="language-html">security.manager.namelist = -java.lang.System.exit \
                            -java.lang.reflect \
                            -java.sql \
                            -javax.tools \
                            -java.io \
                            +java.io.File.getName \
                            +java.io.File.getPath \
                            -sun \
</code></pre>
</div>
<p><code>security.manager.file</code> 和 <code>security.manager.namelist</code> 二选一配置即可。</p>
<p>黑白名单的格式如下：</p> 
<ol> 
 <li><p>前缀符号：</p> 
  <ul> 
   <li><code>+</code> 开头代表白名单</li> 
   <li><code>-</code> 开头代表黑名单</li> 
   <li>没有开始符号，则默认为白名单</li> 
  </ul></li> 
 <li><p>名单格式：</p> 
  <ul> 
   <li>包名： <code>pkg</code></li> 
   <li>类名名： <code>pkg.class</code></li> 
   <li>方法名： <code>pkg.class.method</code></li> 
   <li>字段名： <code>pkg.class.field</code></li> 
  </ul></li> 
</ol>
<p>实例：</p> 
<div class="highlight">
 <pre><code class="language-html">-java.sql                           // 禁止访问 java.sql 下面的任何 Class，包括所有孙子包下面的 Class
-java.lang.System.exit              // 禁止调用 System.exit() 方法
+java.util.Collections.EMPTY_LIST   // 允许访问 Collections.EMPTY_LIST 字段
</code></pre>
</div>
<h2 id="x867245599" class="page-header"><span>1.7 注释指令</span></h2>
<p>由于目前的指令一般直接嵌入在 HTML，对于一些使用可视化编辑器的用户来说，可能会造成一些干扰。<br />模板从 1.0.1 开始增加对指令注释支持，如：<code>&lt;!-- #if (...) --&gt;</code>; 增强对可视化编辑器的友好度。</p>
<p><a name="trim.directive.comments"></a></p>
<h3 id="x557827583" class="page-header"><span>1.7.1 trim.directive.comments</span></h3>
<p>是否开启对注释指令的支持，默认为 <code>false</code>，表示不启用。</p>
<p><a name="trim.directive.comments.prefix"></a></p>
<h3 id="x777542303" class="page-header"><span>1.7.2 trim.directive.comments.prefix</span></h3>
<p>设置注释开始格式，默认为 <code>&lt;!--</code></p>
<p><a name="trim.directive.comments.suffix"></a></p>
<h3 id="x688854496" class="page-header"><span>1.7.3 trim.directive.comments.suffix</span></h3>
<p>设置注释开始格式，默认为 <code>--&gt;</code></p> 
<blockquote>
 <p><strong>注意</strong>： 如果开启注释指令的支持，系统并没有强制要求 <code>trim.directive.comments.prefix</code> 和 <code>trim.directive.comments.suffix</code> 必须配对出现。也就是说如果使用 <code>&lt;!-- #end</code> 也是可以的。当然我们还是建议你配对使用。</p> 
</blockquote>
<p>范例：</p> 
<div class="highlight">
 <pre><code class="language-html">&lt;table&gt;
&lt;!-- #for (User user: userlist) --&gt;
  &lt;tr&gt;
	&lt;td&gt;${user.name}&lt;/td&gt;
	&lt;td&gt;${user.email}&lt;/td&gt;
  &lt;/tr&gt;
&lt;!-- #end --&gt;
&lt;/table&gt;
</code></pre>
</div>
<h2 id="x641838512" class="page-header"><span>1.8 其他选项</span></h2>
<p><a name="trim.directive.line"></a></p>
<h3 id="x1911663233" class="page-header"><span>1.8.1 trim.directive.line</span></h3>
<p>由于指令之间存在很多的空白内容，而空白内容也会被作为原始文本原封不动的输出，这样会造成很多输出的内容参差不齐。这个就是用来优化输出格式的，对于用模板来进行代码生成时候特别有用。不建议关闭。</p>
<p>模板示例：</p> 
<div class="highlight">
 <pre><code class="language-html">#for (int n: [1,2,3])
${n}
#end
</code></pre>
</div>
<p>禁用后效果：<code>false</code></p> 
<div class="highlight">
 <pre><code class="language-html">
1

2

3

</code></pre>
</div>
<p>启用后的效果：<code>true</code> (默认启用)</p> 
<div class="highlight">
 <pre><code class="language-html">1
2
3
</code></pre>
</div>
<h2 id="x793518697" class="page-header"><span>1.9 推荐配置</span></h2>
<h3 id="x746078021" class="page-header"><span>1.9.1 开发环境</span></h3> 
<div class="highlight">
 <pre><code class="language-html">import.packages = pkg1, pkg2
import.autoscan = true
import.autoscan.packages = pkg1, pgk2

template.path = /path/to/templates/
template.reloadable = true

compile.strategy = always
compile.path = /path/to/temp/
compile.debug = true
</code></pre>
</div>
<h3 id="x913514012" class="page-header"><span>1.9.2 生产环境</span></h3> 
<div class="highlight">
 <pre><code class="language-html">import.packages = pkg1, pkg2
import.autoscan = true
import.autoscan.packages = pkg1, pgk2

template.path = /path/to/templates/
template.reloadable = false

compile.strategy = precompile
compile.path = /path/to/temp/
compile.debug = false
</code></pre>
</div>
           	</div>
           </div>
		</div> 
 	</div>
    <!-- Footer
    ================================================== -->
    <footer class="bs-footer" role="contentinfo">
      <div class="container">
        <ul class="footer-links">
          <li>当前版本： v0.0.3</li>
          <li class="muted">&middot;</li>
          <li><a href="http://v2.bootcss.com/">Bootstrap 2.3.2 中文文档</a></li>
          <li class="muted">&middot;</li>
          <li><a href="http://www.bootcss.com">Bootstrap中文网</a></li>
          <li class="muted">&middot;</li>
          <li><a href="http://blog.getbootstrap.com">官方博客</a></li>
          <li class="muted">&middot;</li>
          <li><a href="https://github.com/twbs/bootstrap/issues?state=open">Issues</a></li>
          <li class="muted">&middot;</li>
          <li><a href="https://github.com/twbs/bootstrap/releases">Releases</a></li>
        </ul>
      </div>
    </footer>

    <!-- JS and analytics only. -->
<script src="http://cdn.bootcss.com/jquery/1.10.2/jquery.min.js"></script>
<script src="./assets/js/bootstrap.js"></script>
<script src="http://cdn.bootcss.com/holder/2.0/holder.min.js"></script>
<script src="http://cdn.bootcss.com/highlight.js/7.3/highlight.min.js"></script>
<script >hljs.initHighlightingOnLoad();</script>
<script src="./assets/js/application.js"></script>
<script src="./assets/js/jquery.scrollToTop.min.js"></script>
<script text="javascript/text">
	$(document).ready(function(){
		$("#toTop").scrollToTop(1000);
  		$("table").addClass("table table-bordered");
  	});
</script>
  </body>
</html>
